package legumes.client.ui.admin.stall;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

import legumes.client.evt.manager.EventBusManager;
import legumes.client.evt.store.StoreRemovedEvent;
import legumes.client.evt.store.StoreStateChangedEvent;
import legumes.client.resources.PNResources;
import legumes.client.services.callbacks.GetMessageStoreCallback;
import legumes.client.services.callbacks.GetSellSessionCallback;
import legumes.client.services.callbacks.GetSellSessionIdsCallback;
import legumes.client.services.callbacks.IsStoreOpenedCallback;
import legumes.client.services.callbacks.NewSellSessionCallback;
import legumes.client.services.callbacks.RemoveStoreCallback;
import legumes.client.services.callbacks.SetStoreOpenedCallback;
import legumes.client.services.util.rpc.RPCCallSequencer;
import legumes.client.ui.basket.slate.BasketMainPanel;
import legumes.client.ui.widgets.window.StorePaiementModesEditionWindow;
import legumes.client.ui.widgets.window.StorePlacesDeliveryEditionWindow;
import legumes.client.util.datetime.DateTimeUtils;
import legumes.shared.domain.SellSession;
import legumes.shared.domain.Store;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.smartgwt.client.types.SelectionType;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.tab.TabSet;
import com.smartgwt.client.widgets.tab.events.TabSelectedEvent;
import com.smartgwt.client.widgets.tab.events.TabSelectedHandler;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;

public class AdminStallPanel extends VLayout {
	private AdminOrdersPanel adminOrderpanel;
	private SelectItem stallSelectItem;
	private NewsPanel newsPanel;
	private SellSession sellSession;
	private ToolStripButton openOrCloseStoreButton;
	private DateTimeFormat sellSessionDateTimeFormat = DateTimeFormat.getFormat("EEEE H:m:s");
	private BasketMainPanel mainCenterGridsPanel;
	protected Store store;
	
	public AdminStallPanel(Store store_) {
		super();
		store = store_;
		setWidth100();
		setHeight100();
		
		build();
		initData();
	}
	
	private void build(){
		newsPanel = new NewsPanel();
		setMembersMargin(5);
		setMembers(createToolStrip(), createTabSet(), newsPanel);
	}
	
	private TabSet createTabSet(){
//		bip = new BasketInsidePanel();
//		bop = new BasketOutsidePanel();
		
		TabSet ts = new TabSet();
		ts.setWidth100();
		ts.setHeight100();
		
		Tab stallTab = new Tab();
		stallTab.setTitle("Produits du magasin");
		VLayout vl = new VLayout();
		vl.setWidth100();
		vl.setHeight100();
		mainCenterGridsPanel = new BasketMainPanel(true);
        
		vl.setMembers(mainCenterGridsPanel);//bip, bop);
		stallTab.setPane(vl);
		
		Tab ordersTab = new Tab();
		ordersTab.setTitle("Commandes des clients");
		adminOrderpanel = new AdminOrdersPanel();
		ordersTab.setPane(adminOrderpanel);
		ordersTab.addTabSelectedHandler(new TabSelectedHandler() {
			
			@Override
			public void onTabSelected(TabSelectedEvent event) {
				adminOrderpanel.refreshData();
			}
		});
		ts.setTabs(stallTab, ordersTab);
		
		return ts;
	}
	
	private ToolStrip createToolStrip(){
		ToolStrip toolStrip = new ToolStrip();
		toolStrip.setWidth100();
		toolStrip.setHeight(21);
		
		ToolStripButton newStallButton = new ToolStripButton();  
		newStallButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				SC.confirm("Cr&eacute;ation d'une nouvelle vente",
						"Souhaitez-vous conserver l'&eacute;talage affich&eacute; ?",
						new BooleanCallback() {
							
							@Override
							public void execute(Boolean value) {
								if( value.booleanValue() ){
									callNewSellSession(true);
								} else {
									callNewSellSession(false);
								}
							}
						}
					);
			}
			
		});
		newStallButton.setIcon(PNResources.INSTANCE.addIcon().getURL());  
		newStallButton.setTitle("Nouvelle vente");  
        
        ToolStripButton importStallFromEmailButton = new ToolStripButton();
        importStallFromEmailButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				new StallMailImportDlg(AdminStallPanel.this).draw();
			}
		});
        importStallFromEmailButton.setIcon(PNResources.INSTANCE.emailImportIcon().getURL());  
        importStallFromEmailButton.setTitle("Importer le contenu depuis l'email");  
        
        ToolStripButton deliveryConfigButton = new ToolStripButton();
        deliveryConfigButton.setIcon(PNResources.INSTANCE.deliveryIcon().getURL());  
        deliveryConfigButton.setTitle("Livraison...");  
        deliveryConfigButton.setTooltip("Gérer les modes de livraison...");  
        deliveryConfigButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				onDeliveryConfigAction();
			}
		});
        
        ToolStripButton paiementModesConfigButton = new ToolStripButton();
        paiementModesConfigButton.setIcon(PNResources.INSTANCE.paiementModeMonnaieIcon().getURL());  
        paiementModesConfigButton.setTitle("Paiement...");  
        paiementModesConfigButton.setTooltip("Gérer les modes de paiement...");  
        paiementModesConfigButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				onPaiementModesConfigAction();
			}
		});
        
        
        openOrCloseStoreButton = new ToolStripButton();
        openOrCloseStoreButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				openOrCloseStore();
			}
		});
        openOrCloseStoreButton.setActionType(SelectionType.CHECKBOX);
        openOrCloseStoreButton.setIcon(PNResources.INSTANCE.marketCloseIcon().getURL());  
        openOrCloseStoreButton.setTitle("Fermer le magasin");  
        
        ToolStripButton deleteStoreButton = new ToolStripButton();
        deleteStoreButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				onDeleteStore();
			}
		});
        deleteStoreButton.setIcon(PNResources.INSTANCE.deleteIcon().getURL());  
        deleteStoreButton.setTitle("Supprimer le magasin");  
        
        stallSelectItem = new SelectItem();  
        stallSelectItem.setShowTitle(false);  
        stallSelectItem.setWidth(200);
         
        stallSelectItem.setDefaultValue("Loading...");  
  
        toolStrip.addFormItem(stallSelectItem);  
        toolStrip.addButton(newStallButton);
        toolStrip.addButton(paiementModesConfigButton);
        toolStrip.addButton(deliveryConfigButton);
        toolStrip.addButton(importStallFromEmailButton);  
        toolStrip.addButton(openOrCloseStoreButton);
        toolStrip.addButton(deleteStoreButton);
        
        return toolStrip;
	}
	
	protected void onDeleteStore() {
		if(store!=null){
			SC.confirm("Suppression du magasin", 
					"Etes vous sur de vouloir supprimer le magasin '" + store.getStoreName() + "', " +
					"ainsi que tout son historique de produits et de commandes ?", 
					new BooleanCallback() {
						
						@Override
						public void execute(Boolean value) {
							if(value){
								RPCCallSequencer callSequencer = new RPCCallSequencer();
								final RemoveStoreCallback removeStoreCallback = new RemoveStoreCallback(store);
								callSequencer.addCall(removeStoreCallback);
								callSequencer.addRunnable(new Runnable() {
									public void run() {
										if(removeStoreCallback.isRemovedState()){
											EventBusManager.getInstance().getEventBus().fireEvent(
													new StoreRemovedEvent(store)
											);
										}
									}
								});
								callSequencer.callSequence();
							}
						}
					} );
		}
	}

	private void onPaiementModesConfigAction(){
		new StorePaiementModesEditionWindow(store);
	}
	
	private void onDeliveryConfigAction(){
		new StorePlacesDeliveryEditionWindow(store);
	}
	
	private void initData(){
		RPCCallSequencer callSequencer = new RPCCallSequencer(
		"Chargement des donn&eacute;es...");
	
		// we want the most recent sell session
		final GetSellSessionCallback getOpenedSellSessionCall = 
			new GetSellSessionCallback(-1);
		callSequencer.addCall(getOpenedSellSessionCall);
		
		final GetSellSessionIdsCallback getSellSessionNamesCall = new GetSellSessionIdsCallback();
		callSequencer.addCall(getSellSessionNamesCall);
		
		final IsStoreOpenedCallback getStoreStatusCallback = new IsStoreOpenedCallback();
		callSequencer.addCall(getStoreStatusCallback);
		
		final GetMessageStoreCallback getMessageStoreCallback = new GetMessageStoreCallback();
		callSequencer.addCall(getMessageStoreCallback);
		
		callSequencer.addRunnable(new Runnable() {
			public void run() {
				updateSessionNamesStore(getSellSessionNamesCall.getSellSessionIds());
				stallSelectItem.setDefaultValue( formatSessionDate(
						new Date(getOpenedSellSessionCall.getSellSession().getCreationDate())));
				sellSession = getOpenedSellSessionCall.getSellSession();
				initDataFromSellSession(sellSession);
				newsPanel.initData(getMessageStoreCallback.getStoreMessage());
			}
		
		});
		
		callSequencer.callSequence();
	}
	
	private void initDataFromSellSession(SellSession sellSession_){
		sellSession = sellSession_;
//		bip.initData(sellSession);
//		bop.initData(sellSession);
		mainCenterGridsPanel.initData(null, sellSession.getStall() );
		adminOrderpanel.initData(sellSession.getCreationDate());
	}
	
	public void onStallChanged(){
//		bip.initData(sellSession);
//		bop.initData(sellSession);
	}
	
	public SellSession getSellSession(){
		return sellSession;
	}
	
	protected void updateSessionNamesStore(List<Long> sellSessionIds_) {
		LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>(sellSessionIds_.size());  
	    for (Long date : sellSessionIds_) {
			valueMap.put(Long.toString(date), 
					formatSessionDate(new Date(date)));
		}
		stallSelectItem.setValueMap(valueMap);
		stallSelectItem.updateState();
		GWT.log("updateSessionNamesStore nbr = " + valueMap.size());
	}

	private void callNewSellSession(boolean copyStall_) {
		RPCCallSequencer callSequencer = new RPCCallSequencer(
				"Création en cours...");

		long fromSellSessionId = -1;
		if (copyStall_) {
			fromSellSessionId = sellSession.getCreationDate();
		}

		final NewSellSessionCallback newSellSessionCallback 
			= new NewSellSessionCallback(store, fromSellSessionId);
		callSequencer.addCall(newSellSessionCallback);

		final GetSellSessionIdsCallback getSellSessionIdsCallback = new GetSellSessionIdsCallback();
		callSequencer.addCall(getSellSessionIdsCallback);

		callSequencer.addRunnable(new Runnable() {
			public void run() {
				updateSessionNamesStore(getSellSessionIdsCallback.getSellSessionIds());
				initDataFromSellSession(newSellSessionCallback.getNewSellSession());
			}
		});

		callSequencer.callSequence();
	}
	
	protected void openOrCloseStore() {
		RPCCallSequencer callSequencer = new RPCCallSequencer();

		final IsStoreOpenedCallback getStoreStatusCallback = new IsStoreOpenedCallback();
		callSequencer.addCall(getStoreStatusCallback);

		final SetStoreOpenedCallback setStoreStatusCallback = new SetStoreOpenedCallback(
				false);

		callSequencer.addRunnable(new Runnable() {
			public void run() {
				setStoreStatusCallback.setOpen(!getStoreStatusCallback.isOpened());
			}
		});

		callSequencer.addCall(setStoreStatusCallback);

		callSequencer.addRunnable(new Runnable() {
			public void run() {
				updateOpenCloseStoreButton(!getStoreStatusCallback.isOpened());

				EventBusManager.getInstance().getEventBus().fireEvent(new StoreStateChangedEvent(
							!getStoreStatusCallback.isOpened()));
			}
		});

		callSequencer.callSequence();
	}
	
	protected void updateOpenCloseStoreButton(boolean isStoreOpened_) {
		if (openOrCloseStoreButton.getSelected()) {
			openOrCloseStoreButton.setTitle("Fermer le magasin");
			openOrCloseStoreButton.setIcon(PNResources.INSTANCE.marketCloseIcon().getURL());  
	    } else {
			openOrCloseStoreButton.setTitle("Ouvrir le magasin");
			openOrCloseStoreButton.setIcon(PNResources.INSTANCE.marketOpenIcon().getURL());  
	    }
	}
	
	private String formatSessionDate(Date d_){
		return "Semaine " + DateTimeUtils.getWeek(d_) + " - " + sellSessionDateTimeFormat.format(d_);
		
	}

	public void refreshData() {
		initData();
	}
		
}
